Introduction to Python Functions

Because copy-pasting code is so last semester

Danilo Freire

Emory University

February 07, 2025

Hello, everyone!
Nice to see you all! 😉

Lecture outline

  • Introduction: Why functions?
    • Stop code repetition (DRY, organisation)
  • What are Python functions?
    • def keyword and reusable code blocks
  • Function syntax
    • Function anatomy: name, parameters, body, return, indent
  • Function parameters
    • Positional vs keyword arguments, default values, *args, and **kwargs
  • Best practices and pitfalls
    • Naming, docstrings, indent, return errors
  • Summary and next steps
    • Recap and Q&A

Let’s get started! 🚀

Why functions?

  • The problem: code repetition is a trap!
    • Imagine writing the same code…
    • … again and again and again! 😩
  • An example: greeting many people
    • See the code on the right… Imagine doing this for 1000 names!
  • Inefficient and error-prone
  • Hard to read and maintain
  • Code becomes long and messy
  • Maybe there’s a better way to do this? 🤔
# Greeting people (without functions)
# Don't do this at home!

print("Nice to meet you, Alice!")
print("Nice to meet you, Bob!")
print("Nice to meet you, Charlie!")
print("Nice to meet you, Danilo!")
print("Nice to meet you, Emily!")
print("Nice to meet you, Frank!")
print("Nice to meet you, George!")

# ... and so on for 1000 names...

Yes, there is!

Introducing Python functions

  • Functions are like mini-programs
    • Self-contained blocks of code
    • Designed to perform a specific task
  • Think of them as “recipes” for code: 🧑‍🍳
    • You define the steps (code inside the function)
    • You can “call” the function (use the recipe) whenever you need to perform that task
    • print(), np.mean(), plt.hist() are all functions you’ve used before 🤓
  • Why are they useful?
    • Solve code repetition (as we saw!)
    • Organise your code into logical blocks
    • They are reusable – write once, use many times
    • DRY principle: Don’t Repeat Yourself 😉
# Greeting people (with functions)
# Much better!

def greet(your_name):
    print(f"Nice to meet you, {your_name}!")

greet("Alice")
greet("Bob")
greet("Charlie")
Nice to meet you, Alice!
Nice to meet you, Bob!
Nice to meet you, Charlie!

Anatomy of a Python function

The building blocks

  • Understanding the parts of a function is like learning grammar 🤓📚

  1. def keyword. Tells Python: “We are defining a function now”
  2. Function Name (function_name). The name you’ll use to call the function (choose it wisely!)
  3. Parentheses (). Hold values the function will use. Can be empty () if no input is needed
  4. Parameter(s) (optional) (parameter). A placeholder for the values the function will receive. Can be multiple, separated by commas
  5. Argument(s) (optional) (parameter=argument). The actual values that will be passed to the function.
  6. Colon :. Indicates the function header is complete. Don’t forget it!
  7. Function Body. The actual instructions the function performs. Four spaces!
  8. return statement (optional). The value the function sends back when it’s done. If absent, function returns None

Let’s see two examples together 🛠️

Hello, Alice and Bob!

  • Function 1: say_greeting(name)
def say_greeting(name):
    print(f"Hello, {name}! Nice to see you.")
  • Think about it:
    • What does this function do? Can you identify the parts we discussed?
    • Does it have a return statement?
    • What if we store the output in a variable, like message_alice = say_greeting("Alice")?
say_greeting("Alice")
Hello, Alice! Nice to see you.
message_alice = say_greeting("Alice")
type(message_alice)
Hello, Alice! Nice to see you.
NoneType

Let’s see some examples together 🛠️

Hello, Alice and Bob!

  • And what about this one?
def get_greeting(name, greeting_type="Hello"):
    message = f"{greeting_type}, {name}! Nice to see you."
    return message
  • Think about it:
    • How is this function different from say_greeting?
    • What about the greeting_type="Hello" part? What does it mean?
    • What if you run: message_bob = get_greeting("Bob") and then print(message)?
message_bob = get_greeting("Bob")
type(message_bob)
str
print(message_bob)
Hello, Bob! Nice to see you.

Passing arguments to functions

Positional vs keyword arguments

  • We pass arguments to functions to make them flexible
  • There are two ways to pass arguments:
    • Positional arguments: Order matters!
    • Keyword arguments: Order doesn’t matter
  • Let’s see an example with get_greeting:
def get_greeting(name, greeting_type="Hello"):
    message = f"{greeting_type}, {name}! Nice to see you."
    return message

message = get_greeting("Alice", "Hi")
print(message)
Hi, Alice! Nice to see you.
  • What happens if you switch the order of the arguments?
message = get_greeting("Hi", "Alice")
print(message)
Alice, Hi! Nice to see you.

Keyword arguments

  • If you use keyword arguments, you can pass arguments by name in any order 😉
  • This is especially useful when you have many arguments or default values, so you don’t need to remember which ones come first
message = get_greeting(greeting_type="Hi", name="Alice")
print(message)
Hi, Alice! Nice to see you.
  • Now it works just fine! 🎉

  • The same is true for many functions you use often:

import numpy as np

vector = np.random.normal(size = 4, loc = 10, scale = 2)
print(vector)
[ 8.16558651  9.92852118 11.1184807  12.14625889]
  • So far, so good? 🤓

Let’s create a function together 🛠️

  • Time to put our knowledge to the test! 🚀
  • Let’s create a function that calculates the area of a rectangle
  • Complete the calculate_area function below:
def calculate_area( _______ , _______ ):   # What parameters do we need?
    # Function body - calculate the area
    _______ = _______ * _______           # How do we calculate area? Assign to 'area' variable
    return _______                       # What should the function return?
  • Then, call the function with length=5 and width=4, and print the result
result = calculate_area( _______ , _______ )    # Call with arguments
print(f"The area is: {result}")                # Check if it's correct!

Another one!

Appendix 01: Area of a rectangle

  • Here’s the solution to the exercise:
def calculate_area(length, width):
    area = length * width
    return area

result = calculate_area(5, 4)
print(f"The area is: {result}")
The area is: 20

Back to the function